/*!
 * Crypto-JS v1.1.0
 * http://code.google.com/p/crypto-js/
 * Copyright (c) 2009, Jeff Mott. All rights reserved.
 * http://code.google.com/p/crypto-js/wiki/License
 */
Crypto.mode.CBC = {

    encrypt: function (cipher, m, iv) {

        var blockSizeInBytes = cipher._blocksize * 4;

        // Pad
        m.push(0x80);

        // Encrypt each block
        for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {

            if (offset == 0) {
                // XOR first block using IV
                for (var i = 0; i < blockSizeInBytes; i++)
                    m[i] ^= iv[i];
            }
            else {
                // XOR this block using previous crypted block
                for (var i = 0; i < blockSizeInBytes; i++)
                    m[offset + i] ^= m[offset + i - blockSizeInBytes];
            }

            // Encrypt block
            cipher._encryptblock(m, offset);

        }

    },

    decrypt: function (cipher, c, iv) {

        var blockSizeInBytes = cipher._blocksize * 4;

        // Decrypt each block
        for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {

            // Save this crypted block
            var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);

            // Decrypt block
            cipher._decryptblock(c, offset);

            if (offset == 0) {
                // XOR first block using IV
                for (var i = 0; i < blockSizeInBytes; i++)
                    c[i] ^= iv[i];
            }
            else {
                // XOR decrypted block using previous crypted block
                for (var i = 0; i < blockSizeInBytes; i++)
                    c[offset + i] ^= prevCryptedBlock[i];
            }

            // This crypted block is the new previous crypted block
            var prevCryptedBlock = thisCryptedBlock;

        }

        // Strip padding
        while (c.pop() != 0x80) ;

    }

};
